import {
  useCallback,
  useState,
  useEffect,
  forwardRef,
  useImperativeHandle,
  ForwardedRef,
  ReactNode,
} from 'react';
import { Button, Modal, Table, Input } from '@inbiz/antd';
import { getAllIndexFieldListByIndexName, IField } from '../service';
import { CloseOutlined } from '@ant-design/icons';
import { useMemo } from 'react';
import { getMessage } from '@inbiz/react';
import type { ColumnsType } from 'antd/es/table';
export interface IAddFieldProps {
  type?: string; // 1 搜索字段、2 排序字段、3 列项字段
  showList?: boolean; // 是否显示已经选择的列表
  indexName: string; // 索引库名
  selectionType?: 'checkbox' | 'radio';
  disabledCheckbox?: boolean; //默认选择项，能否取消选中
  title?: string | ((param: { onOpen: () => void; value?: IField[] }) => ReactNode);
  modelTitle: string;
  value?: IField[];
  showType?: string[];
  onChange?: (value: IField[]) => void;
  beforeChange?: (
    value?: (IField & { sort?: string })[],
  ) => (IField & { sort?: string })[] | undefined;
}
export type { IField };
export type IAddField = {
  show: () => void;
  hide: () => void;
};
const fieldData = {} as { [key in string]: IField[] };
export const AddField = forwardRef(
  (
    {
      showType,
      beforeChange,
      selectionType = 'checkbox',
      showList = true,
      modelTitle,
      value,
      title,
      disabledCheckbox,
      indexName,
      onChange,
    }: IAddFieldProps,
    ref: ForwardedRef<IAddField>,
  ) => {
    const columns = useMemo(() => {
      return [
        {
          title: getMessage('SearchResultEngine.fieldName'),
          dataIndex: 'IndexFieldName',
          render: (text: string, row: IField) => (
            <div>
              {text} ({row.IndexFieldType})
            </div>
          ),
        },
        {
          title: getMessage('SearchResultEngine.fieldDescription'),
          dataIndex: 'IndexFieldDesc',
        },
      ];
    }, []);
    const [modelVale, $modelVale] = useState(value || []);
    const [dataSource, $dataSource] = useState<IField[]>([]);
    const [visible, $visible] = useState(false);
    const [search, $search] = useState('');
    useImperativeHandle(
      ref,
      () => ({
        show: () => {
          $visible(true);
        },
        hide: () => {
          $visible(false);
        },
      }),
      [],
    );

    useEffect(() => {
      $modelVale(value || []);
    }, [value]);

    useEffect(() => {
      if (visible) {
        $modelVale(value || []);
        if (fieldData[indexName]) {
          $dataSource([...fieldData[indexName]]);
          return;
        } else {
          getAllIndexFieldListByIndexName(indexName).then((res) => {
            fieldData[indexName] = [...res.Data];
            $dataSource(res.Data);
          });
        }
      } else {
        $search('');
      }
    }, [visible]);

    useEffect(() => {
      // 清除缓存
      return () => {
        delete fieldData[indexName];
      };
    }, []);

    const handleClose = useCallback(
      (type: boolean) => {
        if (type) {
          // const aa = beforeChange?.([...modelVale]) || modelVale!
          
          onChange?.(beforeChange?.([...modelVale]) || modelVale!);
        } else {
          $modelVale([]);
        }
        $visible(false);
        $search('');
      },
      [modelVale, onChange, value, beforeChange],
    );

    const onSelect = useCallback(
      (record: IField, selected: boolean) => {
        if (
          disabledCheckbox &&
          value?.some((item) => item.IndexFieldName === record.IndexFieldName)
        ) {
          return;
        }
        // value中有此项直接返回， 没有时才采用selectedRows 中的值
        $modelVale((list) => {
          if (selectionType === 'checkbox') {
            const newList = [...list];
            if (selected) {
              newList.push(record);
            } else {
              newList.splice(
                newList.findIndex((item) => item.IndexFieldName === record.IndexFieldName),
                1,
              );
            }
            return newList;
          } else {
            return [record];
          }
        });
      },
      [value, selectionType, disabledCheckbox],
    );

    const onSelectAll = useCallback(
      (selected: boolean, selectedRows: IField[]) => {
        if (selected) {
          $modelVale((old) => {
            const checkeds = old?.map((item) => item.IndexFieldName);
            const add = selectedRows.filter(
              (item) => item && !checkeds?.includes(item.IndexFieldName),
            );
            return [...old, ...(add || [])];
          });
        } else {
          if (disabledCheckbox) {
            $modelVale(disabledCheckbox ? value || [] : []);
          } else {
            $modelVale((old) => old.filter((item) => item.notDelete) || []);
          }
        }
      },
      [disabledCheckbox, value],
    );
    // 表格行是否可选择，配置项
    const rowSelection = {
      selectedRowKeys: modelVale.map((value) => value.IndexFieldName),
      onSelect: onSelect,
      onSelectAll: onSelectAll,
      getCheckboxProps: (record: { IndexFieldName: string }) => ({
        // 搜索字段可以取消选中状态，排序字段和列项字段不可以取消选中状态
        disabled:
          value?.find((item) => item.IndexFieldName === record.IndexFieldName)?.notDelete ||
          (disabledCheckbox &&
            value?.some((item) => item.IndexFieldName === record.IndexFieldName)),
        name: record.IndexFieldName,
      }),
    };
    const handelDelete = useCallback(
      (record: IField) => {
        const newVale = [...(value || [])];
        const index = newVale.findIndex((item) => item.IndexFieldName === record.IndexFieldName);
        newVale.splice(index, 1);
        onChange?.(newVale);
      },
      [onChange, value],
    );
    const tableData = useMemo(() => {
      const data = showType?.length
        ? dataSource.filter((item) => showType.includes(item.IndexFieldType))
        : dataSource;
      if (search) {
        return data.filter((item) => {
          return item.IndexFieldName.includes(search) || item.IndexFieldDesc?.includes(search);
        });
      } else {
        return data;
      }
    }, [search, dataSource, showType]);
    const total = useMemo(() => {
      // @ts-ignore
      return modelVale.filter((item) => !item.default)?.length || 0;
    }, [modelVale]);

    const handelClickRew = useCallback(
      (record: IField) => {
        return {
          onClick: () => {
            onSelect(
              record,
              !modelVale.find((item) => item.IndexFieldName === record.IndexFieldName),
            );
          },
        };
      },
      [selectionType, value, modelVale],
    );
    return (
      <div>
        {title &&
          (typeof title === 'string' ? (
            <Button type="primary" onClick={() => $visible(true)}>
              {title}
            </Button>
          ) : (
            title({
              onOpen: () => $visible(true),
              value,
            })
          ))}
        {showList && !!value?.length && (
          <ul className="fieldBox scrollbarHover">
            {value.map((item) => {
              return (
                <li className="fieldItem" key={item.Id}>
                  <p>{item.IndexFieldName}</p>
                  {item.notDelete !== true && <CloseOutlined onClick={() => handelDelete(item)} />}
                </li>
              );
            })}
          </ul>
        )}
        <Modal
          title={modelTitle}
          visible={visible}
          onOk={() => handleClose(true)}
          onCancel={() => handleClose(false)}
          cancelText={getMessage('SearchResultEngine.cancel')}
          okText={getMessage('SearchResultEngine.determine')}
          width={600}
          className="addFieldModel"
        >
          <Input.Search
            placeholder={getMessage('SearchResultEngine.pleaseEnterQueryCriteria')}
            onChange={(e) => $search(e.target.value)}
            onSearch={(value) => $search(value)}
            value={search}
            style={{ width: 270, marginBottom: 20 }}
          />
          <Table
            rowKey={(record) => record.IndexFieldName}
            rowSelection={{
              type: selectionType,
              ...rowSelection,
            }}
            columns={columns}
            dataSource={tableData}
            pagination={false}
            scroll={{ y: 260 }}
            size="small"
            onRow={handelClickRew}
            // footer={() => 'Footer'}
          />
          <div className="selectedNumber">
            {getMessage('SearchResultEngine.numberOfSelected')}：<span>{total}</span>
          </div>
        </Modal>
      </div>
    );
  },
);
AddField.displayName = 'AddField';
